from django.contrib.syndication.views import Feed
from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpResponse, HttpResponseBadRequest
from django.shortcuts import render_to_response, redirect
from django.template.context import Context
from django.template.defaultfilters import register
from django.template.loader import get_template
from django.views.decorators.csrf import csrf_exempt
from communicator.models import Question, User, Answer
from urlparse import  unquote, parse_qs
from communicator.utils import *
import settings

def get_main_page(request):
    user = get_current_user(request)
    return render_to_response("main/index.html", {
        'user_name': user.get_full_name()
    })

def get_editor(request):
    question_id = get_param(request, 'cid')
    content = ''
    if question_id is not None:
        content = Question.get_content(int(question_id))
    return render_to_response("main/editor.html", {
        "cid": question_id,
        "content": content,
    })

def get_rating_page(request):
    users = User.objects.all()
    if users.count() > 0:
        users = list(users)
        users.sort(key=lambda usr: -usr.get_rate_total())
        max_rate = users[0].get_rate_total()
        if max_rate > 0:
            for user in users:
                user.ratio = max(0, user.get_rate_total() * 100 / max_rate)
    return render_to_response("main/rating.html", {
        "users": users
    })

@csrf_exempt
def vote_up_question(request):
    user = get_current_user(request)
    question_id = get_param(request, 'cid')
    votes_num = Question.vote_up(int(question_id), user)
    return HttpResponse(str(votes_num))

@csrf_exempt
def vote_down_question(request):
    user = get_current_user(request)
    question_id = get_param(request, 'cid')
    votes_num = Question.vote_down(int(question_id), user)
    return HttpResponse(str(votes_num))

@csrf_exempt
def add_question(request):
    content = request.raw_post_data
    question_id = get_param(request, 'cid')
    if question_id is None:
        user = get_current_user(request)
        Question.create(user, content)
    else:
        Question.update_content(int(question_id), content)
    return HttpResponse()

@csrf_exempt
def update_question(request, cid):
    content = request.raw_post_data
    if cid is None \
            or len(content) == 0 \
            or request.method != 'POST':
        return HttpResponseBadRequest('Bad request')
    Question.update_content(int(cid), content)
    return HttpResponse()

@csrf_exempt
def add_answer(request):
    user = get_current_user(request)
    question_id = get_param(request, 'cid')
    if question_id is None:
        return HttpResponseBadRequest('Question ID is not provided!')
    question = Question.objects.get(id=int(question_id))
    author = get_current_user(request)
    content = request.raw_post_data
    Answer.create(author, question, content)
    question.touch()
    answers = question.get_answers()
    for item in answers:
        item.aperms = '11' if user == item.author else '01'
        if item.aperms == '01' and item.has_voter(user):
            item.aperms = '00'
    return render_to_response("main/answers.html", {
        "answers": answers
    })

@csrf_exempt
def update_answer(request, cid):
    content = request.raw_post_data
    if cid is None \
            or len(content) == 0 \
            or request.method != 'POST':
        return HttpResponseBadRequest('Bad request')
    Answer.update_content(int(cid), content)
    return HttpResponse()

def get_answers(request):
    user = get_current_user(request)
    question_id = get_param(request, 'cid')
    if question_id is None:
        return HttpResponseBadRequest('Question ID is not provided!')
    question = Question.objects.get(id=int(question_id))
    question.add_viewer(user)
    answers = question.get_answers()
    for item in answers:
        item.set_perms(user)
    return render_to_response("main/answers.html", {
        "answers": answers
    })

@csrf_exempt
def vote_up_answer(request):
    user = get_current_user(request)
    answer_id = get_param(request, 'cid')
    rating = Answer.vote_up(int(answer_id), user)
    return HttpResponse(str(rating))

@csrf_exempt
def vote_down_answer(request):
    user = get_current_user(request)
    answer_id = get_param(request, 'cid')
    rating = Answer.vote_down(int(answer_id), user)
    return HttpResponse(str(rating))

def get_question(request, cid):
    user = get_current_user(request)
    if cid is None:
        return HttpResponseBadRequest('Question ID is not provided!')
    question = Question.objects.get(id=int(cid))
    question.add_viewer(user)
    return render_to_response("feeds/full_question.html", {
        "question": question,
        "answers": question.get_answers()
    })

def get_questions(request):
    query = get_param(request, 'query')
    if query is None:
        return HttpResponseBadRequest('Query string is not provided!')
    page = get_param(request, 'page')
    if page is None:
        return HttpResponseBadRequest('Page number is not provided!')
    query = unquote(query).strip()
    page = int(page)
    questions, pages_count = Question.get_questions(query, page)
    user = get_current_user(request)
    for item in questions:
        item.set_perms(user)

    return render_to_response("main/questions.html", {
        "items_count": len(questions),
        "query": query,
        "prev_page": max(1, page - 1),
        "curr_page": page,
        "next_page": min(pages_count, page + 1),
        "pages_range": range(1, pages_count + 1),
        'questions': questions
    })

@register.filter('add_highlights')
def add_highlights(content, query):
    if len(query) == 0:
        return content
    result = str()
    words = [query.replace(' ', '&nbsp;')]
    words += filter(lambda x: x != '', query.split(' '))
    for line in content.replace('<br>', '\n').splitlines():
        for word in words:
            if word.lower() in line.lower():
                line = replace_word(line, word)
                break
        result += line + '<br>'
    return result

def replace_word(line, word):
    index = line.lower().find(word.lower())
    if index < 0:
        return line
    match = line[index: index + len(word)]
    return line.replace(match, '<span class="qhlight">%s</span>' % match, 1)

def remember_user(request, email):
    try:
        user = User.objects.get(email=email)
    except ObjectDoesNotExist:
        user = User.create(email)
    set_user_id(request, user.id)

@csrf_exempt
def authenticate(request):
    resp = send_post('https://www.google.com/a/globallogic.com/o8/ud', openid_args)
    location = resp.msg.getheader('Location')
    if location is not None:
        return redirect(location)
    else:
        return render_to_response('main/fail.html')

def login(request):
    query = request.META.get('QUERY_STRING', '')
    query = unquote(query)
    args = parse_qs(query)
    handle = args.get('openid.invalidate_handle', [None])[0]
    email = args.get('openid.ext1.value.email', [None])[0]
    if handle != '33xx44pp55uu' \
            or email is None  \
            or not email.endswith('globallogic.com'):
        return render_to_response('main/fail.html')
    else:
        remember_user(request, email)
        return redirect('/')

@csrf_exempt
def logout(request):
    set_user_id(request, None)
    return redirect('/')

@register.filter(name='make_html')
def make_html(value):
    return value.replace('&', '&amp;')\
                .replace('>', '&gt;')\
                .replace('<', '&lt;')\
                .replace('\n', '<br>')\
                .replace(' ', '&nbsp;')\
                .replace('\'', '&#39;')\
                .replace('\"', '&quot;')

class LatestQuestions(Feed):
    title = "N.P.E."
    link = 'http://%s:%d/' % (settings.HOSTNAME, settings.PORT)
    description = "The latest news about BCS headaches"

    def items(self):
        return Question.get_last(10)

    def item_link(self, item):
        return 'http://%s:%d/question/%d?%s' % (settings.HOSTNAME, settings.PORT, item.id, item.timestamp.strftime('%m.%d.%H.%M'))

    def item_title(self, item):
        return '%s, %s' % (item.author.get_short_name(), item.timestamp.strftime('%m/%d at %H:%M'))

    def item_description(self, item):
        t = get_template('feeds/latest_description.html')
        return t.render(Context({'obj': item}))